package classes.multithreading;

/**
 * @author : DuJiabao
 * @Date : 2021/2/8 14:37
 * @Project : java_learning
 * @File : null.java
 * @Desc :
 */
public class ProducerConsumer {
  static final int N = 100;
  static Producer p = new Producer();
  static Consumer c = new Consumer();
  static OurMonitor ourMonitor = new OurMonitor();

  public static void main(String[] args) {
    p.start();
    c.start();
  }

  static class Producer extends Thread {
    @Override
    public void run() {
      while (true) {
        int item = produceItem();
        ourMonitor.insert(item);
      }
    }

    private int produceItem() {
      int item = (int) (Math.random() * 100);
      System.out.println("Produce " + item);
      return item;
    }

  }

  static class Consumer extends Thread {
    @Override
    public void run() {
      while (true) {
        int item = ourMonitor.remove();
        consumeItem(item);
      }
    }

    private void consumeItem(int item) {
      System.out.println("Consume" + item);
    }

  }

  static class OurMonitor {
    private int[] buffer = new int[N];
    private int count = 0;
    private int lo = 0;
    private int hi = 0;

    public synchronized void insert(int val) {
      if (count >= N) goToSleep();
      buffer[hi] = val; // 将数值插进数组中
      hi = (hi + 1) % N;  // 右边的坐标，偏移。当到了尾部的时候，就重新在头部插入
      count++;
      if (count == 1) {
        notify();
      }
    }

    public synchronized int remove() {
      if (count == 0) goToSleep();
      int item = buffer[lo];
      lo = (lo + 1) % N;
      count--;
      if (count < N) notify();
      return item;
    }

    private void goToSleep() {
      try {
        System.out.println(Thread.currentThread().getName() + " go to sleep..........");
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}
